<?php
defined('JOC') or die;

class Render
{
  var $body             = '';
  var $variable_pattern = "/{[(A-Z)\-\_\.\d]+?}/i" ;
  var $block_pattern    = '/<!--\{[^>]*\}-->/' ;
  var $config_begin     = "<!--[config]"  ;
  var $config_end      = "[config]-->" ;
  function __construct( $object , $body = '' )
  {

    $this->body = $body ;

    $this->extractConfig($object);

    $this->body = $this->eval_body($object , $this->body);

  }
  function eval_body( &$object , $text = '' )
  {
    global $params ;

    preg_match_all($this->block_pattern,$text,$match, PREG_OFFSET_CAPTURE);
    $aux = array();
    $fstart = $fstop = false ;
    $control = 0 ;
    $i = 0 ;
    
    do{
      if(!empty($match[0][$i][0]))
      {
        $key = $match[0][$i] ;
        $json = json_decode(substr($key[0],4,-3),true);
        if($json['do'] == 'begin')
        {
          $control++;
          if($control==1){
            $start = $i;
            $fstart = true ;
          }
        }
        else
        {
          if($json['do'] == 'end')
          {
            $control-- ;
            if($control==0)
            {
              $stop = $i ;
              $fstop = true ;
            }
          }
        }
      }
      $i++;
    } while($control > 0) ;
    
    if($fstart && $fstop)
    {
      $setup = isset($match[0][$start][0]) ? json_decode(substr($match[0][$start][0],4,-3),true) : false ;
      
      $beg = substr($text,0,$match[0][$start][1]);
      
      $inner = substr($text,$match[0][$start][1],$match[0][$stop][1] - $match[0][$start][1]);
      $inner = preg_replace($this->block_pattern,'',$inner,1);
      
      $end = substr($text,$match[0][$stop][1]);
      $end = preg_replace($this->block_pattern,'',$end,1);
    	
      if($setup)
      {
      	
        $method = isset($setup['method']) && method_exists(get_class($object), $setup['method'])  ? $setup['method'] : '' ;
        
//        $method = isset($setup['method']) && method_exists(get_class($object), $this->remove_alias($setup['method']) ) ? $this->remove_alias($setup['method']) : '' ;
        
//        debug::pr( $method ) ;
        
				$fake_inner = '';
				
        if($method)
        {

	        $params = isset($setup['params']) ? $setup['params'] : '' ;
//	        debug::pr($setup) ;
	        $arrResult = $object->$method($params);
	        
	        $offset = (isset($setup['offset']) && ( (int)$setup['offset'] < count($arrResult) ) ) ? (int)$setup['offset'] : count($arrResult) ;
	        
//	        debug::pr($arrResult) ;
	        
	        if($arrResult)
	        {
	          for($i = 0 ; $i < $offset;$i++)
	          {

	            $aux = array();
	            if(isset($arrResult[$i]))
	            {
	              if(is_array($arrResult[$i]))
	              {
	                foreach($arrResult[$i] as $key => $value)
	                {
	                  $aux['{'.strtoupper($key).'}'] = $value ;
	                }
	              }
	            }
//	            debug::pr($aux) ;
//	            debug::pr($inner) ;
	            $fake_inner .= !empty($aux) ? strtr($inner,$aux) : $inner ;
	          }
	        }
	        
        }
        $inner = $fake_inner ;
      }

      $inner = $this->eval_body($object , $inner);
      
      $end = $this->eval_body($object , $end);
			
      $text = $beg.$inner.$end ;
      
    }
    
    $text = preg_replace($this->variable_pattern,'',$text);
    
    return $text ;
  }
  function get()
  {
    return $this->body;
  }
  function extractConfig( &$object )
  {
    global $js , $css;
    $start  = strpos($this->body,$this->config_begin) ;
    $stop   = strpos($this->body,$this->config_end) - 1 ;

//    debug::pr($start,'',false);
//    debug::pr($stop,'',false);
//    debug::pr($this->body,'',true);

    $result = substr( $this->body , ( $start + strlen($this->config_begin) ),( $stop - $start ) - strlen($this->config_end) ) ;

//    debug::pr($result ) ;
    
    $this->body = str_replace($this->config_begin.$result.$this->config_end,'', $this->body) ; 

//   debug::pr($this->body) ;
    
    $this->config   = json_decode($result,true) ;

//    debug::pr($this->config,'',false) ;
    
    //run init function
    $method = isset($this->config['init_method']) ? '_read_'.$this->config['init_method'] : '' ; 

    if($object && $method && method_exists(get_class($object),$method) )
    {
      $object->$method();
    }
    else
    {
//      debug::pr(get_class($object).' no contine init_method '.$method ,'render',false);
    }
    //add js and css to global arrays
    if(isset($init['js']) and $init['js'] != '')
    {
      $aux = explode(',',$init['js']);
      foreach($aux as $key)
      {
        array_push($js,$key);
      }
    }
    if(isset($init['css']) and $init['css'] != '')
    {
      $aux = explode(',',$init['css']);
      foreach($aux as $key)
      {
        array_push($css,$key);
      }
    }

  }
  function remove_alias($method = '')
  {
  	return str_replace( strrchr( $method , ":") , '' , $method ) ;
  }
}